﻿#include "EasyTcpClient.h"
#include "CELL.h"
#include "MessageHeader.hpp"
#include "CELLNetWork.hpp"
#include "CELLClient.h"
#include <stdio.h>
#include <string.h>

// 构造
EasyTcpClient::EasyTcpClient()
{

}

// 虚析构
EasyTcpClient::~EasyTcpClient()
{
	Close();
}

// 初始化
int EasyTcpClient::initSocket(int sendSize, int recvSize)
{
	CELLNetWork::Init();
	if (_pClient != nullptr)
	{// 如果已经初始化，先释放
		CELLLog_Warning("close old connect _sock : %d", (int)_pClient->sockfd());
		Close();
	}

	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == SOCKET_ERROR)
	{
		CELLLog_Error("create _sock error");
		return -1;
	}
	else
	{
		// CELLLog_Info("create _sock : %d succssful", (int)sock);
		_pClient = new CELLClient(sock, sendSize, recvSize);
		OnInitSocket();
		return sock;
	}
}

// 连接
int EasyTcpClient::Connect(const char *ip, unsigned short port)
{
	if (_pClient == nullptr)
	{
		if (initSocket() == SOCKET_ERROR)
		{
			return SOCKET_ERROR;
		}
	}

	struct sockaddr_in serv_addr;
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	serv_addr.sin_addr.s_addr = inet_addr(ip);
	int ret = connect(_pClient->sockfd(), (struct sockaddr*) & serv_addr, sizeof(serv_addr));
	if (ret == SOCKET_ERROR)
	{
		CELLLog_Error("<socket=%d>connect  error", (int)_pClient->sockfd());
	}
	else
	{
		_isConnected = true;
		OnConnect();
		// CELLLog_Info("connect to %s:%u successful", ip, port);
	}
	return ret;
}

// 关闭
void EasyTcpClient::Close()
{
	if (_pClient != nullptr)
	{
		delete _pClient;
		_pClient = nullptr;
		_isConnected = false;
	}
}

// 是否工作中
bool EasyTcpClient::IsRun()
{
	return _isConnected;
}

int EasyTcpClient::RecvData()
{
	if (IsRun())
	{
		int nLen = _pClient->RecvData();
		if (nLen > 0)
		{
			DoMsg();
		}
		return nLen;
	}
	return 0;
}

void EasyTcpClient::DoMsg()
{
	while (_pClient->hasMsg())
	{
		OnNetMsg(_pClient->front_msg());
		_pClient->pop_front_msg();
	}
}

// 发送数据
int EasyTcpClient::SendData(DataHeader* header)
{
	if (IsRun())
		return _pClient->SendData(header);
	return 0;
}

int EasyTcpClient::SendData(const char* pData, int nLen)
{
	if (IsRun())
		return _pClient->SendData(pData, nLen);
	return 0;
}
